In this assignment you will develop your initial concept note into a draft of a full project proposal. Treat this assignment as a “dry run” for developing a proposal for a grant or fellowship application, or for your Ph.D. prospectus.
Your proposal should include at least the following sections and information.
The data and the data-generating process
Describe the data set you will be analyzing, and where it comes from, how it was generated and collected. Identify the source of the data. Give a narrative description of the data-generating process: this piece is critical.
Since these will be time series data: identify the frequency of the data series (e.g., hourly, monthly), and the period of record.
esales <- dbGetQuery(db,'SELECT * from eia_elec_sales_va_all_m') # SQL code to retrieve data from a table in the remote database
# str(esales)
esales <- as_tibble(esales) # Convert dataframe to a 'tibble' for tidyverse work
# str(esales)
# Reference: https://arrow.apache.org/docs/r/
# if(!('arrow' %in% installed.packages())) install.packages('arrow')
library(arrow)
write_feather(esales, "esales.feather")
# Close connection -- this is good practice
dbDisconnect(db)
dbUnloadDriver(db_driver)
Exploratory data analysis
library(arrow)
Attaching package: 'arrow'
The following object is masked from 'package:utils':
timestamp
esales <- read_feather("esales.feather")
str(esales)
tibble [233 × 4] (S3: tbl_df/tbl/data.frame)
$ value: num [1:233] 8282 7839 8889 9368 9209 ...
$ date : Date[1:233], format: "2020-05-01" "2020-04-01" ...
$ year : int [1:233] 2020 2020 2020 2020 2020 2019 2019 2019 2019 2019 ...
$ month: int [1:233] 5 4 3 2 1 12 11 10 9 8 ...
Provide a brief example of the data, showing how they are structured.
print(esales)
# A tibble: 233 x 4
value date year month
<dbl> <date> <int> <int>
1 8282. 2020-05-01 2020 5
2 7839. 2020-04-01 2020 4
3 8889. 2020-03-01 2020 3
4 9368. 2020-02-01 2020 2
5 9209. 2020-01-01 2020 1
6 10038. 2019-12-01 2019 12
7 9291. 2019-11-01 2019 11
8 8757. 2019-10-01 2019 10
9 9874. 2019-09-01 2019 9
10 10912. 2019-08-01 2019 8
# … with 223 more rows
# References: https://www.tidyverse.org/, https://dplyr.tidyverse.org/
esales %>%
filter(year == 2019) %>%
filter(value > 9000) %>%
print()
# A tibble: 10 x 4
value date year month
<dbl> <date> <int> <int>
1 10038. 2019-12-01 2019 12
2 9291. 2019-11-01 2019 11
3 9874. 2019-09-01 2019 9
4 10912. 2019-08-01 2019 8
5 11527. 2019-07-01 2019 7
6 9903. 2019-06-01 2019 6
7 9147. 2019-05-01 2019 5
8 9466. 2019-03-01 2019 3
9 9148. 2019-02-01 2019 2
10 10925. 2019-01-01 2019 1
esales %>%
group_by(month) %>%
summarise(mean = mean(value)) -> mean_esales_by_month
`summarise()` ungrouping output (override with `.groups` argument)
esales %>%
mutate(sales_TWh = value/1000) %>%
select(-value)
# filter(data object, condition) : syntax for filter() command
Plot the time series.
#Reference: https://ggplot2.tidyverse.org/
ggplot(data=esales, aes(x=date,y=value)) +
geom_line() + xlab("Year") + ylab("Virginia monthly total electricity sales (GWh)")

# install.packages("tsibble")
library(tsibble) # Reference: https://tsibble.tidyverts.org/articles/intro-tsibble.html
Attaching package: 'tsibble'
The following object is masked from 'package:lubridate':
interval
esales %>% as_tsibble(index = date) -> esales_tbl_ts
print(esales_tbl_ts)
# A tsibble: 233 x 4 [1D]
value date year month
<dbl> <date> <int> <int>
1 9576. 2001-01-01 2001 1
2 7820. 2001-02-01 2001 2
3 8070. 2001-03-01 2001 3
4 7153. 2001-04-01 2001 4
5 7224. 2001-05-01 2001 5
6 8264. 2001-06-01 2001 6
7 8896. 2001-07-01 2001 7
8 9404. 2001-08-01 2001 8
9 7753. 2001-09-01 2001 9
10 7272. 2001-10-01 2001 10
# … with 223 more rows
library(lubridate) # Make it easy to deal with dates
esales_tbl_ts %>% filter(month==3)
esales_tbl_ts %>% filter(month(date)==3)
esales_tbl_ts %>%
select(date, sales_GWh = value) -> elsales_tbl_ts
print(elsales_tbl_ts)
# A tsibble: 233 x 2 [1D]
date sales_GWh
<date> <dbl>
1 2001-01-01 9576.
2 2001-02-01 7820.
3 2001-03-01 8070.
4 2001-04-01 7153.
5 2001-05-01 7224.
6 2001-06-01 8264.
7 2001-07-01 8896.
8 2001-08-01 9404.
9 2001-09-01 7753.
10 2001-10-01 7272.
# … with 223 more rows
Perform and report the results of other exploratory data analysis
hist(elsales_tbl_ts$sales_GWh, breaks=40)

# install.packages("feasts")
library(feasts)
Loading required package: fabletools
elsales_tbl_ts %>%
mutate(Month = yearmonth(date)) %>%
as_tsibble(index = Month) -> vaelsales_tbl_ts
vaelsales_tbl_ts %>% gg_season(sales_GWh, labels = "both") + ylab("Virginia electricity sales (GWh)")

# install.packages('tsibbledata')
library(tsibbledata)
aus_production
aus_production %>% gg_season(Electricity)

aus_production %>% gg_season(Beer)

vaelsales_tbl_ts %>%
gg_subseries(sales_GWh)

# aus_production %>% gg_subseries(Beer)
vaelsales_tbl_ts %>% filter(month(Month) %in% c(3,6,9,12)) %>% gg_lag(sales_GWh, lags = 1:2)

vaelsales_tbl_ts %>% filter(month(Month) == 1) %>% gg_lag(sales_GWh, lags = 1:2)

vaelsales_tbl_ts %>% ACF(sales_GWh) %>% autoplot()

# if(!('fpp3' %in% installed.packages())) install.packages('fpp3')
library(fpp3)
── Attaching packages ────────────────────────────────────────────── fpp3 0.3 ──
✓ fable 0.2.1
── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
x lubridate::date() masks base::date()
x dplyr::filter() masks stats::filter()
x tsibble::interval() masks lubridate::interval()
x dplyr::lag() masks stats::lag()
# decompose(vaelsales_tbl_ts)
vaelsales_tbl_ts %>%
model(STL(sales_GWh ~ trend(window=21) + season(window='periodic'), robust = TRUE)) %>%
components() %>%
autoplot()

vaelsales_tbl_ts %>%
mutate(ln_sales_GWh = log(sales_GWh)) %>%
model(STL(ln_sales_GWh ~ trend(window=21) + season(window='periodic'),
robust = TRUE)) %>%
components() %>%
autoplot()

vaelsales_tbl_ts %>%
features(sales_GWh, feat_stl)
vaelsales_tbl_ts %>%
features(sales_GWh, feature_set(pkgs="feasts"))
Warning: `n_flat_spots()` is deprecated as of feasts 0.1.5.
Please use `longest_flat_spot()` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.
Statistical model
Discussion of the statistical model
Describe how the formal statistical model captures and aligns with the narrative of the data-generating process. Flag any statistical challenges raised by the data generating process, e.g. selection bias; survivorship bias; omitted variables bias, etc.
Plan for data analysis
Describe what information you wish to extract from the data. Do you wish to… estimate the values of the unobserved model parameters? create a tool for forecasting? estimate the exceedance probabilities for future realizations of \(y_t\)?
Describe your plan for getting this information. OLS regression? Some other statistical technique?
If you can: describe briefly which computational tools you will use (e.g., R), and which packages you expect to draw on.
LS0tCnRpdGxlOiAgICAgIlByb2plY3QgUHJvcG9zYWwgSW5zdHJ1Y3Rpb25zIHdpdGggZXhhbXBsZSBjb2RlIgppbnN0aXR1dGU6ICJTWVMgNzAzMCBUaW1lIFNlcmllcyBBbmFseXNpcyAmIEZvcmVjYXN0aW5nLCBGYWxsIDIwMjAiIAphdXRob3I6ICAgICAiSW5zdHJ1Y3RvcjogQXJ0aHVyIFNtYWxsIgpkYXRlOiAgICAgICAiVmVyc2lvbiBvZiBgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogICAjIHBkZl9kb2N1bWVudDoKICAgIyAgIHRvYzogZmFsc2UKICBodG1sX25vdGVib29rOgogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICBjb2RlX2ZvbGRpbmc6IHNob3cgIyBvcHRpb25zOiBzaG93LCBoaWRlCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgaHRtbF9kb2N1bWVudDoKICAgICAgICBrZWVwX21kOiB5ZXMKICAjIHBkZl9kb2N1bWVudDogZGVmYXVsdApiaWJsaW9ncmFwaHk6IC9Vc2Vycy9BcnRodXIvR2l0UmVwb3MvVGVhY2hpbmcvdGltZS1zZXJpZXMvdHNlcmllcy5iaWIKbGluay1jaXRhdGlvbnM6IHllcwotLS0KCkluIHRoaXMgYXNzaWdubWVudCB5b3Ugd2lsbCBkZXZlbG9wIHlvdXIgaW5pdGlhbCBjb25jZXB0IG5vdGUgaW50byBhIGRyYWZ0IG9mIGEgZnVsbCBwcm9qZWN0IHByb3Bvc2FsLiBUcmVhdCB0aGlzIGFzc2lnbm1lbnQgYXMgYSAiZHJ5IHJ1biIgZm9yIGRldmVsb3BpbmcgYSBwcm9wb3NhbCBmb3IgYSBncmFudCBvciBmZWxsb3dzaGlwIGFwcGxpY2F0aW9uLCBvciBmb3IgeW91ciBQaC5ELiBwcm9zcGVjdHVzLgoKWW91ciBwcm9wb3NhbCBzaG91bGQgaW5jbHVkZSBhdCBsZWFzdCB0aGUgZm9sbG93aW5nIHNlY3Rpb25zIGFuZCBpbmZvcm1hdGlvbi4KCioqRnJvbnQgbWF0dGVyOioqIERlc2NyaXB0aXZlIHRpdGxlLCB5b3VyIG5hbWUsIGRhdGUsIHJlZmVyZW5jZSB0byAiU1lTIDcwMzAgVGltZSBTZXJpZXMgQW5hbHlzaXMgJiBGb3JlY2FzdGluZywgRmFsbCAyMDIwIi4KCioqQWJzdHJhY3Q6KiogQSB2ZXJ5IGJyaWVmIHN1bW1hcnkgb2YgdGhlIHByb2plY3QuCgojIEludHJvZHVjdGlvbgoKR2l2ZSBhIG5hcnJhdGl2ZSBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvYmxlbSB5b3UgYXJlIGFkZHJlc3NpbmcsIGFuZCB0aGUgbWV0aG9kcyB5b3Ugd2lsbCB1c2UgdG8gYWRkcmVzcyBpdC4gUHJvdmlkZSBjb250ZXh0OgoKLSAgIFdoYXQgaXMgdGhlIHF1ZXN0aW9uIHlvdSBhcmUgYXR0ZW1wdGluZyB0byBhbnN3ZXI/Ci0gICBXaHkgaXMgdGhpcyBxdWVzdGlvbiBpbXBvcnRhbnQ/IChXaG8gY2FyZXM/KQotICAgSG93IHdpbGwgeW91IGdvIGFib3V0IGF0dGVtcHRpbmcgdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb24/CgpUaGlzIHdvcmsgYWRkcmVzc2VzIHRoZSBxdWVzdGlvbjogV2h5IGRvIHBlb3BsZSBub3QgdXNlIHByb2JhYmlsaXN0aWMgZm9yZWNhc3RzIGZvciBkZWNpc2lvbi1tYWtpbmcgW0Bjb3VuY2lsQ29tcGxldGluZ0ZvcmVjYXN0Q2hhcmFjdGVyaXppbmcyMDA3XT8KCiMgVGhlIGRhdGEgYW5kIHRoZSBkYXRhLWdlbmVyYXRpbmcgcHJvY2VzcwoKRGVzY3JpYmUgdGhlIGRhdGEgc2V0IHlvdSB3aWxsIGJlIGFuYWx5emluZywgYW5kIHdoZXJlIGl0IGNvbWVzIGZyb20sIGhvdyBpdCB3YXMgZ2VuZXJhdGVkIGFuZCBjb2xsZWN0ZWQuIElkZW50aWZ5IHRoZSBzb3VyY2Ugb2YgdGhlIGRhdGEuIEdpdmUgYSBuYXJyYXRpdmUgZGVzY3JpcHRpb24gb2YgdGhlIGRhdGEtZ2VuZXJhdGluZyBwcm9jZXNzOiB0aGlzIHBpZWNlIGlzIGNyaXRpY2FsLgoKU2luY2UgdGhlc2Ugd2lsbCBiZSB0aW1lIHNlcmllcyBkYXRhOiBpZGVudGlmeSB0aGUgZnJlcXVlbmN5IG9mIHRoZSBkYXRhIHNlcmllcyAoZS5nLiwgaG91cmx5LCBtb250aGx5KSwgYW5kIHRoZSBwZXJpb2Qgb2YgcmVjb3JkLgoKYGBge3Igc2V0IHVwIGNvZGluZyBlbnZpcm9ubWVudCwgaW5jbHVkZT1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBsaWJyYXJ5KGRwbHlyKSAtLSBkb24ndCBuZWVkIHRoaXMgaWYgeW91IGFyZSBsb2FkaW5nIHRoZSBlbnRpcmUgJ3RpZHl2ZXJzZScgc3VpdGUKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobHVicmlkYXRlKSAjIEZvciBlYXN5IGhhbmRsaW5nIG9mIHRpbWUtaW5kZXhlZCBvYmplY3RzCmBgYAoKYGBge3Igb3BlbiBjb25uZWN0aW9uIHRvIGRhdGFiYXNlLCBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIE9wZW4gY29ubmVjdGlvbiB0byBhIHJlbW90ZSBkYXRhYmFzZQojIE1ha2Ugc3VyZSB5b3VyIFZQTiBuZXR3b3JrIGNvbm5lY3Rpb24gaXMgYWN0aXZlIGlmIG5lZWRlZCEKCiMgaWYoISgnUlBvc3RncmVTUUwnICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKCkpKSBpbnN0YWxsLnBhY2thZ2VzKCdSUG9zdGdyZVNRTCcpCmxpYnJhcnkoUlBvc3RncmVTUUwpCgojICJteV9wb3N0Z3Jlc19jcmVkZW50aWFscy5SIiBjb250YWlucyB0aGUgbG9nLWluIGluZm9ybWF0aW9uCnNvdXJjZSgiL1VzZXJzL0FydGh1ci9HaXRSZXBvcy9UZWFjaGluZy9teV9wb3N0Z3Jlc19kYl9jcmVkZW50aWFscy5SIikKCiMgT3BlbiBjb25uZWN0aW9uCmRiX2RyaXZlciA8LSBkYkRyaXZlcigiUG9zdGdyZVNRTCIpCmRiIDwtIGRiQ29ubmVjdChkYl9kcml2ZXIsdXNlcj11c2VyLCBwYXNzd29yZD1wYXNzd29yZCxkYm5hbWU9InBvc3RncmVzIiwgaG9zdD1ob3N0KQpybShwYXNzd29yZCkgCgojIGNoZWNrIHRoZSBjb25uZWN0aW9uOiBJZiBmdW5jdGlvbiByZXR1cm5zIHZhbHVlIFRSVUUsIHRoZSBjb25uZWN0aW9uIGlzIHdvcmtpbmcKZGJFeGlzdHNUYWJsZShkYiwgIm1ldGFkYXRhIikKYGBgCgpgYGB7ciByZXRyaWV2ZSBkYXRhIGZyb20gZGIsIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cgplc2FsZXMgPC0gZGJHZXRRdWVyeShkYiwnU0VMRUNUICogZnJvbSBlaWFfZWxlY19zYWxlc192YV9hbGxfbScpICMgU1FMIGNvZGUgdG8gcmV0cmlldmUgZGF0YSBmcm9tIGEgdGFibGUgaW4gdGhlIHJlbW90ZSBkYXRhYmFzZQojIHN0cihlc2FsZXMpCmVzYWxlcyA8LSBhc190aWJibGUoZXNhbGVzKSAjIENvbnZlcnQgZGF0YWZyYW1lIHRvIGEgJ3RpYmJsZScgZm9yIHRpZHl2ZXJzZSB3b3JrCiMgc3RyKGVzYWxlcykKYGBgCgpgYGB7ciBzYXZlIGRhdGEgaW4gQXBhY2hlIEFycm93IGZvcm1hdCwgZXZhbD1GQUxTRX0KIyBSZWZlcmVuY2U6IGh0dHBzOi8vYXJyb3cuYXBhY2hlLm9yZy9kb2NzL3IvCiMgaWYoISgnYXJyb3cnICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKCkpKSBpbnN0YWxsLnBhY2thZ2VzKCdhcnJvdycpCmxpYnJhcnkoYXJyb3cpCndyaXRlX2ZlYXRoZXIoZXNhbGVzLCAiZXNhbGVzLmZlYXRoZXIiKQpgYGAKCmBgYHtyIGNsb3NlIGRiIGNvbm5lY3Rpb24sIGV2YWw9RkFMU0V9CiMgQ2xvc2UgY29ubmVjdGlvbiAtLSB0aGlzIGlzIGdvb2QgcHJhY3RpY2UKZGJEaXNjb25uZWN0KGRiKQpkYlVubG9hZERyaXZlcihkYl9kcml2ZXIpCmBgYAoKIyBFeHBsb3JhdG9yeSBkYXRhIGFuYWx5c2lzCgpgYGB7ciByZWFkIGluIGRhdGF9CmxpYnJhcnkoYXJyb3cpCmVzYWxlcyA8LSByZWFkX2ZlYXRoZXIoImVzYWxlcy5mZWF0aGVyIikKCnN0cihlc2FsZXMpCmBgYAoKIyMgUHJvdmlkZSBhIGJyaWVmIGV4YW1wbGUgb2YgdGhlIGRhdGEsIHNob3dpbmcgaG93IHRoZXkgYXJlIHN0cnVjdHVyZWQuCgpgYGB7ciBwcmludCB0aGUgZGF0YSBhcyBhIHRhYmxlfQpwcmludChlc2FsZXMpCmBgYAoKYGBge3IgdXNlIHRpZHl2ZXJzZSBzeW50YXggdG8gcGVyZm9ybSBzb21lIHNpbXBsZSBkYXRhIG1hbmlwdWxhdGlvbnN9CiMgUmVmZXJlbmNlczogaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy8sIGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy8KCmVzYWxlcyAlPiUKICBmaWx0ZXIoeWVhciA9PSAyMDE5KSAlPiUKICBmaWx0ZXIodmFsdWUgPiA5MDAwKSAlPiUKICBwcmludCgpCgplc2FsZXMgJT4lCiAgZ3JvdXBfYnkobW9udGgpICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbih2YWx1ZSkpIC0+IG1lYW5fZXNhbGVzX2J5X21vbnRoCgplc2FsZXMgJT4lCiAgbXV0YXRlKHNhbGVzX1RXaCA9IHZhbHVlLzEwMDApICU+JQogIHNlbGVjdCgtdmFsdWUpCiAgCiMgZmlsdGVyKGRhdGEgb2JqZWN0LCBjb25kaXRpb24pIDogc3ludGF4IGZvciBmaWx0ZXIoKSBjb21tYW5kCmBgYAoKIyMgUGxvdCB0aGUgdGltZSBzZXJpZXMuCgpgYGB7ciB1c2UgZ2dwbG90MiB0byBnZW5lcmF0ZSBhIHBsb3R9CiNSZWZlcmVuY2U6IGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnLwoKZ2dwbG90KGRhdGE9ZXNhbGVzLCBhZXMoeD1kYXRlLHk9dmFsdWUpKSArIAogIGdlb21fbGluZSgpICsgeGxhYigiWWVhciIpICsgeWxhYigiVmlyZ2luaWEgbW9udGhseSB0b3RhbCBlbGVjdHJpY2l0eSBzYWxlcyAoR1doKSIpCgpgYGAKCgoKCmBgYHtyfQojIGluc3RhbGwucGFja2FnZXMoInRzaWJibGUiKQpsaWJyYXJ5KHRzaWJibGUpICMgUmVmZXJlbmNlOiBodHRwczovL3RzaWJibGUudGlkeXZlcnRzLm9yZy9hcnRpY2xlcy9pbnRyby10c2liYmxlLmh0bWwKCmVzYWxlcyAlPiUgYXNfdHNpYmJsZShpbmRleCA9IGRhdGUpIC0+IGVzYWxlc190YmxfdHMKCnByaW50KGVzYWxlc190YmxfdHMpCmBgYAoKYGBge3J9CmxpYnJhcnkobHVicmlkYXRlKSAjIE1ha2UgaXQgZWFzeSB0byBkZWFsIHdpdGggZGF0ZXMKCmVzYWxlc190YmxfdHMgJT4lIGZpbHRlcihtb250aD09MykKCmVzYWxlc190YmxfdHMgJT4lIGZpbHRlcihtb250aChkYXRlKT09MykKCmVzYWxlc190YmxfdHMgJT4lCiAgc2VsZWN0KGRhdGUsIHNhbGVzX0dXaCA9IHZhbHVlKSAtPiBlbHNhbGVzX3RibF90cwoKcHJpbnQoZWxzYWxlc190YmxfdHMpCmBgYAoKCgoKIyMgUGVyZm9ybSBhbmQgcmVwb3J0IHRoZSByZXN1bHRzIG9mIG90aGVyIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMKCgpgYGB7ciBtYWtlIGEgaGlzdG9ncmFtIG9mIHRoZSBkYXRhfQoKaGlzdChlbHNhbGVzX3RibF90cyRzYWxlc19HV2gsIGJyZWFrcz00MCkKYGBgCgoKYGBge3J9CiMgaW5zdGFsbC5wYWNrYWdlcygiZmVhc3RzIikKbGlicmFyeShmZWFzdHMpCgplbHNhbGVzX3RibF90cyAlPiUgCiAgbXV0YXRlKE1vbnRoID0geWVhcm1vbnRoKGRhdGUpKSAlPiUgCiAgYXNfdHNpYmJsZShpbmRleCA9IE1vbnRoKSAtPiB2YWVsc2FsZXNfdGJsX3RzCgoKdmFlbHNhbGVzX3RibF90cyAlPiUgZ2dfc2Vhc29uKHNhbGVzX0dXaCwgbGFiZWxzID0gImJvdGgiKSArIHlsYWIoIlZpcmdpbmlhIGVsZWN0cmljaXR5IHNhbGVzIChHV2gpIikKYGBgCgpgYGB7cn0KIyBpbnN0YWxsLnBhY2thZ2VzKCd0c2liYmxlZGF0YScpCmxpYnJhcnkodHNpYmJsZWRhdGEpCgphdXNfcHJvZHVjdGlvbgoKYXVzX3Byb2R1Y3Rpb24gJT4lIGdnX3NlYXNvbihFbGVjdHJpY2l0eSkKCmF1c19wcm9kdWN0aW9uICU+JSBnZ19zZWFzb24oQmVlcikKCgpgYGAKYGBge3J9CnZhZWxzYWxlc190YmxfdHMgJT4lIAogIGdnX3N1YnNlcmllcyhzYWxlc19HV2gpCgojIGF1c19wcm9kdWN0aW9uICU+JSBnZ19zdWJzZXJpZXMoQmVlcikKYGBgCgpgYGB7ciBwbG90IGxhZ2dlZCB2YWx1ZXN9CnZhZWxzYWxlc190YmxfdHMgICU+JSBmaWx0ZXIobW9udGgoTW9udGgpICVpbiUgYygzLDYsOSwxMikpICU+JSBnZ19sYWcoc2FsZXNfR1doLCBsYWdzID0gMToyKQoKdmFlbHNhbGVzX3RibF90cyAgJT4lIGZpbHRlcihtb250aChNb250aCkgPT0gMSkgJT4lIGdnX2xhZyhzYWxlc19HV2gsIGxhZ3MgPSAxOjIpCmBgYAoKYGBge3J9CnZhZWxzYWxlc190YmxfdHMgJT4lIEFDRihzYWxlc19HV2gpICU+JSBhdXRvcGxvdCgpCmBgYAoKYGBge3IgcGVyZm9ybSBhdXRvbWF0ZWQgdGltZSBzZXJpZXMgZGVjb21wb3NpdGlvbn0KIyBpZighKCdmcHAzJyAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpKSkgaW5zdGFsbC5wYWNrYWdlcygnZnBwMycpCmxpYnJhcnkoZnBwMykKCiMgZGVjb21wb3NlKHZhZWxzYWxlc190YmxfdHMpCmBgYAoKCmBgYHtyIHBlcmZvcm0gYWRkaXRpdmUgU1RMIGRlY29tcG9zaXRpb24gb2YgdGhlIFZBIGVsZWN0cmljaXR5IHNhbGVzIHRpbWUgc2VyaWVzfQp2YWVsc2FsZXNfdGJsX3RzICU+JQogIG1vZGVsKFNUTChzYWxlc19HV2ggfiB0cmVuZCh3aW5kb3c9MjEpICsgc2Vhc29uKHdpbmRvdz0ncGVyaW9kaWMnKSwgcm9idXN0ID0gVFJVRSkpICU+JQogIGNvbXBvbmVudHMoKSAlPiUKICBhdXRvcGxvdCgpCmBgYAoKYGBge3IgcGVyZm9ybSBtdWx0aXBsaWNhdGl2ZSBTVEwgZGVjb21wb3NpdGlvbiBvZiB0aGUgVkEgZWxlY3RyaWNpdHkgc2FsZXMgdGltZSBzZXJpZXN9CnZhZWxzYWxlc190YmxfdHMgJT4lCiAgbXV0YXRlKGxuX3NhbGVzX0dXaCA9IGxvZyhzYWxlc19HV2gpKSAlPiUKICBtb2RlbChTVEwobG5fc2FsZXNfR1doIH4gdHJlbmQod2luZG93PTIxKSArIHNlYXNvbih3aW5kb3c9J3BlcmlvZGljJyksCiAgICByb2J1c3QgPSBUUlVFKSkgJT4lCiAgY29tcG9uZW50cygpICU+JQogIGF1dG9wbG90KCkKYGBgCmBgYHtyfQp2YWVsc2FsZXNfdGJsX3RzICU+JQogIGZlYXR1cmVzKHNhbGVzX0dXaCwgZmVhdF9zdGwpCmBgYApgYGB7cn0KdmFlbHNhbGVzX3RibF90cyAlPiUKICBmZWF0dXJlcyhzYWxlc19HV2gsIGZlYXR1cmVfc2V0KHBrZ3M9ImZlYXN0cyIpKQpgYGAKCgojIFN0YXRpc3RpY2FsIG1vZGVsCgojIyBGb3JtYWwgbW9kZWwgb2YgZGF0YS1nZW5lcmF0aW5nIHByb2Nlc3MKCldyaXRlIGRvd24gYW4gZXF1YXRpb24gKG9yIHNldCBvZiBlcXVhdGlvbnMpIHRoYXQgcmVwcmVzZW50IHRoZSBkYXRhLWdlbmVyYXRpbmcgcHJvY2VzcyBmb3JtYWxseS4KCkZvciB0aGUgZWxlY3RyaWNpdHkgc2FsZXMgZGF0YSwgbWF5YmUgdGhlIHByb2Nlc3MgbG9va3MgbGlrZToKCiQkIHlfdCA9IFRyZW5kX3QgWCBTZWFzb25hbF90IFggUmVzaWR1YWxfdCAkJAokJCB5X3QgPSBcYmV0YV8wICsgXGJldGFfMSB0ICsgXGJldGFfMiBtICsgXHZhcmVwc2lsb25fdCAkJAoKCgoKCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyBFVFMgZm9yZWNhc3RzClVTQWNjRGVhdGhzICU+JQogIGV0cygpICU+JQogIGZvcmVjYXN0KCkgJT4lCiAgYXV0b3Bsb3QoKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQpzdHIodGF5bG9yKQpwbG90KHRheWxvcikKYGBgCgoKCklmIGFwcGxpY2FibGU6IGRlc2NyaWJlIGFueSB0cmFuc2Zvcm1hdGlvbnMgb2YgdGhlIGRhdGEgKGUuZy4sIGRpZmZlcmVuY2luZywgdGFraW5nIGxvZ3MpIHlvdSBuZWVkIHRvIG1ha2UgdG8gZ2V0IHRoZSBkYXRhIGludG8gYSBmb3JtIChlLmcuLCBsaW5lYXIpIHJlYWR5IGZvciBudW1lcmljYWwgYW5hbHlzaXMuCgpXaGF0IGtpbmQgb2YgcHJvY2VzcyBpcyBpdD8gJEFSKHApJD8gV2hpdGUgbm9pc2Ugd2l0aCBkcmlmdD8gU29tZXRoaW5nIGVsc2U/CgpXcml0ZSBkb3duIGFuIGVxdWF0aW9uIGV4cHJlc3NpbmcgZWFjaCByZWFsaXphdGlvbiBvZiB0aGUgc3RvY2hhc3RpYyBwcm9jZXNzICR5X3QkIGFzIGEgZnVuY3Rpb24gb2Ygb3RoZXIgb2JzZXJ2ZWQgZGF0YSAod2hpY2ggY291bGQgaW5jbHVkZSBsYWdnZWQgdmFsdWVzIG9mICR5JCksIHVub2JzZXJ2ZWQgcGFyYW1ldGVycyAoJFxiZXRhJCksIGFuZCBhbiBlcnJvciB0ZXJtICgkXHZhcmVwc2lsb25fdCQpLiBFeDoKCiQkeSA9IFhcY2RvdFxiZXRhICsgXHZhcmVwc2lsb24kJCBBZGQgYSBtb2RlbCBvZiB0aGUgZXJyb3IgcHJvY2Vzcy4gRXg6ICRcdmFyZXBzaWxvbiBcc2ltIE4oMCwgXHNpZ21hXjIgSV9UKSQuCgojIyBEaXNjdXNzaW9uIG9mIHRoZSBzdGF0aXN0aWNhbCBtb2RlbAoKRGVzY3JpYmUgaG93IHRoZSBmb3JtYWwgc3RhdGlzdGljYWwgbW9kZWwgY2FwdHVyZXMgYW5kIGFsaWducyB3aXRoIHRoZSBuYXJyYXRpdmUgb2YgdGhlIGRhdGEtZ2VuZXJhdGluZyBwcm9jZXNzLiBGbGFnIGFueSBzdGF0aXN0aWNhbCBjaGFsbGVuZ2VzIHJhaXNlZCBieSB0aGUgZGF0YSBnZW5lcmF0aW5nIHByb2Nlc3MsIGUuZy4gc2VsZWN0aW9uIGJpYXM7IHN1cnZpdm9yc2hpcCBiaWFzOyBvbWl0dGVkIHZhcmlhYmxlcyBiaWFzLCBldGMuCgojIFBsYW4gZm9yIGRhdGEgYW5hbHlzaXMKCkRlc2NyaWJlIHdoYXQgaW5mb3JtYXRpb24geW91IHdpc2ggdG8gZXh0cmFjdCBmcm9tIHRoZSBkYXRhLiBEbyB5b3Ugd2lzaCB0by4uLiBlc3RpbWF0ZSB0aGUgdmFsdWVzIG9mIHRoZSB1bm9ic2VydmVkIG1vZGVsIHBhcmFtZXRlcnM/IGNyZWF0ZSBhIHRvb2wgZm9yIGZvcmVjYXN0aW5nPyBlc3RpbWF0ZSB0aGUgZXhjZWVkYW5jZSBwcm9iYWJpbGl0aWVzIGZvciBmdXR1cmUgcmVhbGl6YXRpb25zIG9mICR5X3QkPwoKRGVzY3JpYmUgeW91ciBwbGFuIGZvciBnZXR0aW5nIHRoaXMgaW5mb3JtYXRpb24uIE9MUyByZWdyZXNzaW9uPyBTb21lIG90aGVyIHN0YXRpc3RpY2FsIHRlY2huaXF1ZT8KCklmIHlvdSBjYW46IGRlc2NyaWJlIGJyaWVmbHkgd2hpY2ggY29tcHV0YXRpb25hbCB0b29scyB5b3Ugd2lsbCB1c2UgKGUuZy4sIFIpLCBhbmQgd2hpY2ggcGFja2FnZXMgeW91IGV4cGVjdCB0byBkcmF3IG9uLgoKIyBTdWJtaXNzaW9uIHJlcXVpcmVtZW50cwoKUHJlcGFyZSB5b3VyIHByb3Bvc2FsIHVzaW5nIE1hcmtkb3duLiAoWW91IG1heSBmaW5kIGl0IHVzZWZ1bCB0byBnZW5lcmF0ZSB5b3VyIE1hcmtkb3duIGZpbGUgZnJvbSBzb21lIG90aGVyIHRvb2wsIGUuZy4gUiBNYXJrZG93biBpbiBSIFN0dWRpby4pIFN1Ym1pdCB5b3VyIHByb3Bvc2FsIGJ5IHB1c2hpbmcgaXQgdG8geW91ciByZXBvIHdpdGhpbiB0aGUgY291cnNlIG9yZ2FuaXphdGlvbiBvbiBHaXRodWIuIFdoZW4geW91ciBwcm9wb3NhbCBpcyByZWFkeSwgbm90aWZ5IHRoZSBpbnN0cnVjdG9yIGJ5IGFsc28gY3JlYXRpbmcgYSBzdWJtaXNzaW9uIGZvciB0aGlzIGFzc2lnbm1lbnQgb24gQ29sbGFiLiBQbGVhc2UgYWxzbyB1cGxvYWQgYSBQREYgdmVyc2lvbiBvZiB5b3VyIHByb3Bvc2FsIHRvIENvbGxhYiBhcyBwYXJ0IG9mIHlvdXIgc3VibWlzc2lvbi4KCiMgQ29tbWVudAoKRGVwZW5kaW5nIG9uIHlvdXIgcHJpb3IgZXhwZXJpZW5jZSwgeW91IG1heSBmaW5kIHRoaXMgYXNzaWdubWVudCBjaGFsbGVuZ2luZy4gVHJlYXQgdGhpcyBhc3NpZ25tZW50IGFzIGFuIG9wcG9ydHVuaXR5IHRvIG1ha2UgcHJvZ3Jlc3Mgb24geW91ciBvd24gcmVzZWFyY2ggcHJvZ3JhbS4gTWFrZSB5b3VyIHByb3Bvc2FsIGFzIGNvbXBsZXRlIGFzIHlvdSBjYW4uIEJ1dCBub3RlIHRoYXQgdGhpcyBhc3NpZ25tZW50IGlzIG1lcmVseSB0aGUgRmlyc3QgRHJhZnQuIFlvdSB3aWxsIGhhdmUgbW9yZSBvcHBvcnR1bml0eSB0byByZWZpbmUgeW91ciB3b3JrIG92ZXIgdGhlIG5leHQgdHdvIG1vbnRocywgaW4gY29uc3VsdGF0aW9uIHdpdGggdGhlIGluc3RydWN0b3IsIHlvdXIgYWR2aXNvciwgYW5kIHlvdXIgY2xhc3NtYXRlcy4KCiMgUmVmZXJlbmNlcwo=